<?php
if(!defined('BASE_DIR'))die('Cannot access the file !');
/**
 * -+-----------------------------------------
 * |PHP Framework
 * |Copyright (c) 2010 jinke.[iblue.cc]
 * |E-mail: mejinke@gmail.com
 * |Date: 2010-03-08
 * |Update: 2011-01-06
 * -+-----------------------------------------
 *
 * 系统控制器基础类 ，所有的控制器都应继承此类
 * @author jinke
 */
class Controller extends Base
{

	/**
	 * 当前请求的控制器 controller
	 * @var string
	 */
	protected  $controller = '';

	/**
	 * 当前请求的动作 Action
	 * @var string
	 */
	protected  $action = '';

	/**
	 * URI参数列表
	 * @var array
	 */
	protected  $args = array();

	/**
	 * 控制器子类
	 * @var object
	 */
	private $object = null ;




	/**
	 * 语言包
	 * @var array
	 */
	public $lang = array();

	protected $tpl_name = '';
	protected $cache = 0;
	protected $isecho = true;
	protected $tpl_path ='';


	/**
	 * 构造函数 获取相关资料
	 * @access	public
	 * @param	object	$object	 继承此类的子类
	 */
	public function __construct(Controller $object = null)
	{
		$this->object = $object ;
		//获取需要调用的控制器 controller
		$this->controller =$this->getRouter()->getControllerName();
		//获取动作 Action
		$this->action = $this->getRouter()->getActionName();
		//获取参数 args
		$this->args = Functions::GET();

		Debug::initClass('Controller.class.php');
	}


	/**
	 * 填充模板资料
	 * @access protected
	 * @param string $key 键
	 * @param mixed 值
	 * @return void
	 */
	protected function assign($key,$val)
	{
		if(!empty($key))
		{
			$this->FW_View->add($key,$val);
		}
	}


	/**
	 * 渲染模板 并输出
	 * @access protected
	 * @return void
	 */
	protected function show()
	{
		//填充语言包
		$this->FW_View->add('lang',$this->lang);
		$this->FW_View->show($this->tpl_name,$this->cache,$this->isecho,$this->tpl_path, '', debug_backtrace());
		$this->tpl_name = '';
		$this->cache = 0;
		$this->isecho = true ;
		$this->tpl_path = '';
	}


	/**
	 * 检测是否存在缓存文件
	 * @access private
	 * @return void
	 */
	private function checkCache()
	{

		//分析模板名称
		empty($this->tpl_name) ? $this->tpl_name = $this->action.'.html' : $this->tpl_name = $this->tpl_name.'.html';

		//缓存目录
		$tpl_cache_dir = TEMP_DIR.'cache/tpl/'.APP_NAME.'/'.$this->controller.'/';

		//缓存文件
		$tpl_cache_file	= strtolower($tpl_cache_dir.$this->tpl_name);

		if(is_file($tpl_cache_file))
		{
			$content = file_get_contents($tpl_cache_file);
			preg_match('/\{##Create-Time:(.*)?##\}/',$content,$tep_array);
			if(isset($tep_array[1]))
			{
				$d = explode('_',$tep_array[1]);

				if(Files::isDated($tpl_cache_file,$d[1]))
					return null;
				else
				{
					return str_replace($tep_array[0],'',$content);
				}
			}
		}
		else
			return null;
	}

	/**
	 * 执行子类动作
	 * @access public
	 * @return void
	 */
	public function doAction()
	{
		$content = $this->checkCache();
		if($content!==null)
			echo $content;
		else
		{
			$valiMethod = 'validate'.ucfirst($this->action).'Action';
			$method = $this->action.'Action';
			$method_rep = Config::get('action_rep');
			
			if (method_exists($this->object, $valiMethod))
			{
				if(call_user_func(array($this->object,$valiMethod)) === true)
				{
					if (method_exists($this->object, $method))
						call_user_func(array($this->object,$method));
					elseif (method_exists($this->object, $method_rep))
						call_user_func(array($this->object,$method_rep));
					else
						message_404();
				}
			}
			else 
			{
				if (method_exists($this->object, $method))
					call_user_func(array($this->object,$method));
				elseif (method_exists($this->object, $method_rep))
					call_user_func(array($this->object,$method_rep));
				else
					message_404();
			}
		}
	}


	/**
	 * 设置表单提交令牌
	 * @access public
	 * @param int $sum 表单个数，令牌个数
	 * @return void
	 */
	public function setToken($sum=1)
	{
		$this->FW_View->setToken($sum);
	}
	
	
	/**
	 * 设置模板布局文件
	 * @access protected
	 * @param string $layout
	 * @return bool
	 */
	protected function setLayout($layout)
	{
		if(!is_string($layout)) return false;
		$this->FW_View->setLayout($layout);
	}



	/**
	 * 令牌检测
	 * @access public
	 * @parame string $action 所在的action[可选]
	 * @return bool
	 */
	public function checkToken($action='')
	{
		if($action=='')
			$action=$this->_router->getAction();

		//获取令牌值
		$tokens	=	$this->_session->get(strtolower(APP_NAME.'_'.$this->controller.'_'.$action.'_token'));

		if(!is_array($tokens))
			return false;

		$keys = array_keys($tokens);
		$vals = array_values($_POST);

		$flag=0;
		//循环检测是否存在令牌
		for($i=0;$i<count($keys);$i++)
		{
			//如果发现存在Token ，则进行数据校验
			if(isset($_POST[$keys[$i]]))
			{
				if($_POST[$keys[$i]]!=$tokens[$keys[$i]])
					return	false;
				else
					$flag++;
			}
		}

		if($flag==count($keys))
			return true;
		else
			return false;
	}


	/**
	 * 析构函数 自动输出模板
	 * @access public
	 * @return void
	 */
	public function __destruct()
	{	
		//如果子类有显示申明__destruct时必需调用父类的析构函数，即 parent::__destruct();
		if(Config::get('auto_output_view')=== true )
			$this->show();
	}


}

?>